#include "Texture1D.hpp"
#include <Utility/Tools.hpp>
#include <Math/Vector4.hpp>
#include <Math/Vector3.hpp>

namespace zzz{

Texture1D::Texture1D(int newiformat)
:Texture(GL_TEXTURE_1D, newiformat), width_(0)
{}

Texture1D::Texture1D(zuint width, int newiformat)
:Texture(GL_TEXTURE_1D, newiformat)
{}

bool Texture1D::Bind(GLenum bindto/*=GL_TEXTURE0*/)
{
  int lastLevel;
  glGetIntegerv(GL_ACTIVE_TEXTURE,&lastLevel);

  glActiveTexture(bindto);
  Disable(bindto);
  glEnable(GL_TEXTURE_1D);
  GLBindTexture1D::Set(GetID());

  glActiveTexture(lastLevel);
  CHECK_GL_ERROR()
  return true;
}

void Texture1D::Create(zuint width)
{
  if (width_==width)
    return;
  width_=width;
  Bind();
  glTexImage1D(GL_TEXTURE_1D,0,internal_format_,width_,0,0,0,NULL);
  CHECK_GL_ERROR()
}

void Texture1D::ChangeInternalFormat(int newiformat)
{
  if (internal_format_==newiformat) return;
  Vector4f *data=new Vector4f[width_];
  TextureToData(data);
  internal_format_=newiformat;
  DataToTexture(data,width_);
  delete[] data;
  CHECK_GL_ERROR()
}

void Texture1D::ChangeSize(zuint width)
{
  if (width==width_) return;
  Vector4f *data=new Vector4f[width_];
  TextureToData(data);
  width_=width;
  DataToTexture(data,width);
  delete[] data;
  CHECK_GL_ERROR()
}

void Texture1D::ChangeSize(zuint width,zuint useless)
{
  ChangeSize(width);
}

void Texture1D::ChangeParameter(GLenum filter,GLenum wrap)
{
  Bind();
  if (filter!=0)
  {
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, filter);
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, filter);
  }
  if (wrap!=0)
  {
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, wrap);
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, wrap);
  }
  filter_para_=filter;
  wrap_para_=wrap;
  CHECK_GL_ERROR()
}

template<>
void Texture1D::DataToTexture(const Vector3f *v, zsize size)
{
  Bind();
  glTexImage1D(GL_TEXTURE_1D,0,internal_format_,size,0,GL_RGB,GL_FLOAT,v);
  width_=size;
  CHECK_GL_ERROR()
}

template<>
void Texture1D::TextureToData(Vector3f *v)
{
  Bind();
  glGetTexImage(GL_TEXTURE_2D,0,GL_RGB,GL_FLOAT,v);
  CHECK_GL_ERROR()
}


}